package edu.nf.test.demo;

import java.lang.reflect.Field;

/**
 * @author CSY
 * @date 2025 - 04 - 16
 * 字段注入处理器
 */
public class FieldInjectHandler {
    /**
     * 对字段进行依赖注入的方法
     * 需要参数 - 需要进行依赖注入的对象
     * 获取到对象中的所有字段并循环遍历 - 包含私有字段
     * 判断其中的字段是否存在注入注解@Inject
     * 如果存在该注解那么就获取到注解的值
     * 根据注解获取到的值在工厂容器中查找与之匹配的键并获取到对象
     * 由于@Inject注解中的值必须是@Component注解值存在的值
     * 所以必定或匹配到，在根据工厂的方法进行返回对象
     * 对字段进行设置值
     * @param instance 要进行依赖注入的对象
     * @param containerFactory 容器工厂
     */
    public void handle(Object instance,ContainerFactory containerFactory) {
        for (Field field : instance.getClass().getDeclaredFields()) {
            if (field.isAnnotationPresent(Inject.class)) {
                String name = field.getAnnotation(Inject.class).value();
                Object instanceObj = containerFactory.getBean(name);

                setValue(field,instance,instanceObj);
            }

        }

    }

    private void setValue(Field field, Object instance, Object value) {
        try {
            if (!field.canAccess(instance)) {
                field.setAccessible(true);
            }
            field.set(instance,value);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}
